home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1996 April
/
CHIP 1996 aprilis (CD06).zip
/
CHIP_CD06.ISO
/
hypertxt.arj
/
9302
/
HERC2.CD
< prev
next >
Wrap
Text File
|
1995-04-18
|
20KB
|
325 lines
@VGrafikus konvertálások -- 2.@N
@VMonokróm üzemmód@N
A megjelenítés bizonyos szempontból egyszerûbb, mint az
alkotó szándékának ""kitalálgatása", de több, más jellegû
nehézséget rejt magában. Elôször is: a megjelenítendô
információ többnyire nem szürkeárnyalatok formájában van
megadva.
Színes információ esetén a vörös, zöld és kék telítettségi
tényezôk különbözô értékeket vesznek fel, így át kell ôket
alakítanunk. Ezek a tényezôk voltaképpen az adott alapszín
fényességét jelzik, a három egyenrangú alapszín teljes
telítettsége pedig összeadódva alkotja a legnagyobb
fényességû színt, a fehéret. Ezért például a teljes
telítettségû vörös önmagában még csak 255 harmadrészének a
fényességét adja, 85-öt. Ha meg akarjuk határozni egy pont
fényességét, akkor tehát össze kell adnunk a komponensek
harmadrészét. Sokkal egyszerûbb azonban a @Kfényesség =@N
@K(vörös komponens + zöld komponens + kék komponens) / 3@N
képlet használata.
@VA legegyszerûbb módszer@N
Ha már elô tudjuk állítani egy pont szürkeségi értékét,
akkor megkísérelhetjük egy nagyon gyors, de nem túl jó
minôségû eljárás használatát. Egyszerûen elindulunk a bal
felsô sarokból, és minden pontról eldöntjük, sötétebb vagy
világosabb-e a 127-es félfényességnél. Elôbbi esetben
fekete, míg az utóbbiban értelemszerûen fehér pixelt
rendelünk a fényességértékhez. Az algoritmus meglehetôs
primitívsége ritkán vezet szép képekhez, többnyire piszkos
vonalrajzokat és kifestôkönyvekre emlékeztetô ábrákat
kapunk. Mégis, még ma is használják különbözô
megjelenítôprogramok, hiszen egyszerû beprogramozni és
képcsoportok gyors áttekintéséhez tökéletesen megfelel.
@VMerev raszterszórás@N
Ebben az eljárásban minden egyes, az átviteli file által
meghatározott pixelhez egy @KX*X@N-es rasztert rendelünk.
Az @KX@N nem lehet nagy, érthetôen, mivel most nem
engedhetjük meg az egymásbacsúszást, és a felbontás
automatikusan @K1/X@N-edére csökken. Az @KX*X@N-es
raszterbe @KY@N darab fehér pontot kell tennünk. @KY@N úgy
aránylik @KX*X@N-hez, mint a számolt fényességérték a
255-höz: @KY = (X*X) * (fényesség / 255)@N. Az @KY@N
számú pontot a lehetô legelszórtabban kell elhelyezni a
raszteren belül, hogy az minél homogénebb hatást nyújtson.
Az elszórtságra nemcsak a raszteren belül kell figyelnünk,
hanem az egymás melletti azonos raszterek viszonylatában
is. Elsô ábránk néhány tippet mutat be az elrendezésre
2*2-es és 3*3-as raszterekben.
Ez az eljárás valamivel jobb képeket készít, mint a
közelítô színválasztás, mégis, több szempontból
kívánnivalókat hagy maga után. A felbontás csökkentése
megbocsáthatatlan bûnnek tûnik, ráadásul elkerülhetô. A
kifejezhetô szürkeárnyalatok száma viszonylag kicsi: 2*2-es
rasztereknél 5, 3*3-asoknál 10 különbözô fényesség
lehetséges. Mindezek miatt ez az algoritmus sem igazán
alkalmas élvezhetô képek elôállítására.
@VRelatív címzésû raszterszórás@N
Elôször növeljük meg az árnyalatok számát, mondjuk 65-re.
Ez 8*8-as rasztert feltételez, egyelôre ezzel fogunk
dolgozni. Tervezzük meg a 65 árnyalathoz tartozó 65
különbözô rasztert. Értelemszerûen minden lépésnél további
egy fehér pontot kell elhelyeznünk a 8*8-as mezôben akkor,
ha a feketétôl indultunk és egyesével haladunk a fehér felé
(így a legegyszerûbb).
Egy pont helyének kiválasztásakor mindig arra kell
figyelnünk, hogy az a lehetô legtávolabb legyen a már
meglévô többi fehér ponttól a raszteren belül, és az egymás
mellé helyezett ugyanilyen raszterekben is. Ha tehát az
elsô pontot a bal felsô sarokba (0;0) tettük, akkor a
következôt nem rakhatjuk a jobb alsó sarokba (7;7) mivel ez
a pont a sarkával érintkezne a rasztertôl jobbra lefelé
lévô, ugyanilyen raszter bal felsô pixelével. Elôfordul,
hogy már annyira tele van a raszter, hogy a következô pont
mindenképpen érintkezni fog egy vagy több ponttal. Fontos,
hogy a sarkaikkal illetve lapjaikkal érintkezô pixelek
távolsága eltér: ha két, lapjával érintkezô képpont
középpontja egységnyi távolságú, akkor a sarkukkal
érintkezô képpontok közepe négyzetgyök 2 egységre van
egymástól. Persze az sem mindegy, hogy hány ponttal
érintkezne a következô pixel: minél kevesebbel, annál jobb.
Egy ekkora rasztert még kézzel is meg lehet tervezni, de
aki szeret programozgatni, annak azt ajánlom, készítsen egy
64 elemû tömböt. Egy dupla ciklussal tapogassuk le a teljes
8*8-as mezôt, minden fehér pontból induljunk el mind a 8
irányba (jobbra, balra, le, föl és a köztes irányokba), s
átlagoljuk, hogy a legközelebbi fehér pontok milyen távol
vannak az adott képelemtôl -- a négy fôirányban 1-es, a
négy átlós irányban pedig 1,41-os szorzót alkalmazva. A
már fehér elemeket eleve ki kell zárni a lehetôségek közül.
A végén válasszuk ki a 64 átlagból a legnagyobbat. Ide kell
kerülnie a következô képelemnek. Ez így megy egészen
félfényességig, 31-ig. Innen fordítva kell tovább haladni
65-ig, a teljes fényességig. Csak a fekete pontokkal
dolgozunk, a fekete pontoktól vett távolságokat figyeljük,
s az átlagok közül mindig a legkisebbet kell kiválasztanunk
-- ott lesz a következô fehér pont.
Fontos, hogy két szomszédos fényességértékû raszter csak
egyetlen pontban különbözhet egymástól. A 23-as raszter
például maximum egy plusz pixelt tartalmazhat a 22-eshez
képest, a többi 22 pixelt nem rendezhetjük át a raszteren
belül. Enélkül nagyon csúf fényességi gócpontok
alakulhatnak ki a képernyôn két különbözô fényességû
raszter találkozásánál. A második ábra szemlélteti, hogyan
célszerû megoldani az elrendezést.
Most már elég árnyalatunk van, oldjuk meg a felbontás
problémáját is. Ha egyszerûen hozzárendelnénk 8*8-as
raszterünket a kapott fényességértékhez, akkor 1/8 részére
csökkenne ez a fontos jellemzô -- ami megengedhetetlen.
Próbáljuk ki a következôt. A képernyôt gondolatban hálózzuk
be egy négyzetráccsal úgy, hogy minden nyolcadik pixelre
essen egy fonál. Feleltessük meg a négyzetrács minden
rácspontját a 8*8-as raszterünk bal felsô sarkának. Ezt a
méretbeli azonosság miatt nyugodtan megtehetjük. Most a
képernyô minden egyes fizikai pontjáról el tudjuk dönteni,
hogy vízszintes és függôleges irányban milyen messze van a
rácsponttól, vagyis a megtervezett raszterünk melyik
pixelére esik (lásd a harmadik ábrát).
Módosítsuk úgy a raszterképzô eljárásunkat, hogy határozza
meg minden egyes pont helyét az adott raszteren belül. Ha
nehézségeink adódnának, akkor az @KX1 = X mod 8@N és @KY1 =@N
@KY mod 8@N képletekkel próbálkozhatunk, ahol @KX@N és @KY@N
a fizikai cím, @KX1@N és @KY1@N a raszteren belül
koordináta, a @Kmod@N pedig egy egész számokkal dolgozó
osztás, amely mindig lefelé kerekít és eredményként az
osztás maradékát adja vissza.
Ha egy adott rácson belül mind a 64 pontnak azonos a
fényessége -- az (X;Y) pontról pedig úgy döntjük el fekete
vagy fehér voltát, hogy meghatározzuk raszterbeli helyét és
az ehhez tartozó értéket kiolvassuk a kívánt fényességû
raszterbôl --, akkor az adott rácsban fizikailag megjelenô
ponthalmaz megegyezik majd a kívánt fényességû raszter
mátrixhalmazával, a megfelelô árnyalatot hozva létre ezzel.
Ha egy adott rács pixeleinek nem azonos a fényességértéke,
akkor a 8*8-as mezôn belüli relatív pozíció meghatározása
után azon raszter megfelelô pontját kell kiolvasni, amely
leginkább kifejezi az ábrázolandó képpont kívánt
fényességét. Azt, hogy milyen rasztereket kell
felhasználnunk, egy egyszerû képlet segítségével
kitalálhatjuk: @Kraszter = max raszterek * (fényesség /@N
@K255)@N.
A relatív címzés trükkjének felhasználásával elértük, hogy
egy adott rasztermezôn belül megfelelô élességgel
ábrázolhassunk fényességi határokat, ezen túl viszont
megtarthassuk az átmeneti árnyalatok és a homogén felületek
egyenletességét. A legfontosabb, hogy az eljárással most
már fizikai pixelekre címezhetünk, akár 64 különbözô
fényességértéket megadva a háló adott rácsán belül. Az
elôre elkészített raszterek gondoskodnak arról, hogy mindez
a lehetô legpontosabban jelenjen meg a képernyôn.
îgy már van 65 különbözô szürkeárnyalatunk, és a felbontást
is megôriztük. Mielôtt elbíznánk magunkat és a jól végzett
munka törékeny illúziójának kártékony hatása alá kerülnénk,
rá kell jöjjünk, a módszer korántsem tökéletes. Az eljárás
viszonylag szép képeket készít ugyan, mégis van egy apró
hibája. Ez pedig a mátrixok fénycsíkjainak vonalba
rendezôdése. Ez a vonalba rendezôdés azért következik be,
mert a raszterek tervezése során végig arra figyeltünk,
hogy a lehetô legtávolabb kerüljenek egymástól az azonos
színû pontok. Emiatt a szigorú matematikai pontossággal
elrendezett pixelek az emberi szemben egyenes vonalakká,
szimmetrikus mértani formákká olvadnak össze, lerontva a
homogén hatást.
@VTovábbfejlesztett raszterszórás@N
A raszterek megtervezését kell tehát módosítani úgy, hogy
kiküszöböljük a vonalhatást. Most már nem úszhatjuk meg a
programozást. Az elvégzendô mûveletsor oly összetett, hogy
a ""találomra" végzett kézi tervezés alighanem totális
csôdhöz vezet. Ha nem voltunk lusták megírni az elsô
rasztertípus tervezô algoritmusát, akkor mázlink van.
Néhány módosítással elintézhetjük a dolgot.
Elôször is, a letapogatás során nemcsak azt kell
megállapítani minden egyes pozícióról, hogy milyen
átlagtávolságra vannak a legközelebbi pixelek, hanem azt
is, hogy a négy fô- és a négy átlós irányban hány azonos
színû pixellel esne egy vonalba az adott pozícióra
helyezendô képelem 8 egységen belül. Ha a számlálás közben
kicsúszunk a raszter területérôl, akkor térjünk vissza az
ellentétes oldal megfelelô eleménél. Ezek szerint össze
kell adni azoknak az azonos színû pixeleknek a számát,
amelyek 8 egység távolságon belül rajta vannak azon a 4
félegyenesen, amelyek a vizsgált pixelbôl indulnak ki a
négy fô- és a négy átlós irányba.
Most jön a döntô különbség: a 64 elembôl nem azt választjuk
ki, amelyiknél a legnagyobb az azonos pixelek
átlagtávolsága, hanem azt/azokat, ahol a legkevesebb azonos
színû pixellel esne egy vonalba az új pixel. Persze ha több
ilyen helyet is találunk, akkor ezekbôl azt választjuk ki,
amelyiknél a legnagyobb az átlagtávolság. A módszer
félfényességnél itt is átvált, akárcsak az elsô tervezô
algoritmus: a fekete pixeleket figyeli, és fordítva veszi
figyelembe az eredményeket.
Ha jól írtuk meg az eljárást, akkor már alighanem az elsô
próbálkozások is felülmúlhatatlan sikerélményt jelentenek a
felkészületlen programozó számára. A még igényesebbek
belevághatnak a 16*16-os és 32*32-es raszterek
kidolgozásába. Minden ugyanúgy mûködik, csak a konstansok
nônek kétszeresükre, illetve csökkennek felére a funkciótól
függôen.
@VEgydimenziós hibaszórás@N
Ez a módszer teljesen más elvet követ, mint az elôzôk, így
a vele készített képek is jelentôsen eltérnek a
megszokottól. Furcsa sajátosság, hogy a módszer a kép
készítése közben fellépô hibák -- ábrázolási pontatlanságok
-- felhalmozódására épít, és ezeket az eltéréseket próbálja
kompenzálni minden egyes új pixel felhordásánál. A hiba
akkor keletkezik, amikor a kívánt árnyalatot nem lehet
kifejezni egy mátrix segítségével, azaz szinte állandóan.
Ha csak fekete és fehér színekkel rendelkezünk, akkor
bármely köztes árnyalat kifejezésekor pontatlanság lép fel,
ezt pedig elôbb-utóbb korrigálni kell.
Ha elsôként egy közel negyedfényességû pixelt kell
kiraknunk (60-as fényesség), akkor értelemszerûen a feketét
választjuk, hiszen az a kívánt árnyalathoz legközelebb lévô
""valódi" szín. Máris megjelenik a hiba, hiszen nem
negyedfényességet fejeztünk ki, hanem teljes sötétséget. A
hiba súlyossága az eltéréssel arányos, ezért azt így is
jegyezzük fel. Ha a következô pixel is 60-as fényességû,
mi ismét fekete pixelt választunk, még egyszer elkövetve az
elôbbi pontatlanságot. Most már kétszer olyan súlyos a
hiba. Ha azt akarjuk, hogy ez az árnyalati tévedés
megszûnjön, akkor a felhalmozódott hibát valahogy be kell
csempésznünk a pixelszín eldöntésének a folyamatába.
Kézenfekvônek tûnik, hogy minden lépésnél összeadogatjuk a
keletkezô pontatlanságokat, és az összeget megpróbáljuk
""jóváírni" a következô mátrixpont bejövô alapértékén.
A hibaszórásos algoritmus egydimenziós változata pontosan
ezt teszi. Fenntart egy hibaváltozót, amiben azt tárolja,
mekkora eltérést kellene korrigálni az adott pillanatban,
és ezt a változót mindig módosítja annak megfelelôen, hogy
többet, avagy kevesebbet fejezett ki a kívántnál. A
hibaváltozó értéke lehet negatív is. Ez akkor következik
be, ha a kifejezendô árnyalat a félfényességen felül volt,
de még nem érte el a fehér szintjét.
A pontatlanság ""jóváírása" úgy történik, hogy az éppen
kifejezendô fényességhez hozzáadjuk a hibaváltozó értékét.
Ha a mátrixpont így átbillen feketébôl fehérbe -- vagy
fordítva --, akkor a korrekció megtörtént. Talán
túlságosan is -- újabb hiba, ezúttal ellenkezô elôjellel.
Természetesen a hibaváltozó kezdôértéke nulla, s amíg nem
követünk el hibát, nincs mit korrigálni.
Nem kell semmi mást tennünk, mint hogy elindulunk a kép
egyik sarkából, és pixelenként, sorfolytonosan -- ettôl
egydimenziós az eljárás -- végrehajtjuk a következô
bekezdés mûveletsorát.
Lekérjük az ábrázolandó pixel eredeti fényességértékét.
Ehhez hozzáadjuk a hibaváltozót (ez kivonást is jelenthet).
Errôl a korrigált fényességértékrôl eldöntjük, hogy fehér,
avagy fekete pixelt igényel -- félfényesség felett vagy
alatt van-e. Kirakjuk a képernyôre a szükséges mátrixot,
végül a hibaváltozóhoz hozzáadjuk az eredeti fényességérték
és a képernyôre küldött pixel fényességértékének (0 vagy
255) a különbségét. Képlettel: @Khiba = hiba + (eredeti@N
@Kérték - mátrix fényesség)@N. A képernyôsorok elején
nullázhatjuk a hibaváltozót, de nem ajánlatos. Többnyire
nem túl zavaróak az átcsúszott korrekciós mátrixok,
ellenben a raszterpontok jóval szétszórtabban helyezkednek
majd el egymás alatt, kellemes homogén hatást nyújtva.
Természetesen a hibaszórásos algoritmusnak is vannak
fejlettebb, rendkívül bonyolult és idôigényes változatai.
Ez a verzió gyors, viszonylag egyszerû, és az esetek
többségében gyönyörû képeket hoz létre. Ha nem láttunk még
hasonló algoritmussal létrehozott, tetszetôs árnyaltságú
raszterábrákat, akkor aligha akarjuk majd elhinni: hûséges
monokróm monitorunk még mindig a jó öreg 720*348-as,
kétszínû üzemmódban villódzik.
Noha az eljárások elsôsorban arra valók, hogy az eltérô
üzemmódok között szabad átjárást biztosítsanak a különbözô
képek számára, akik figyeltek, alighanem rájöttek már, hogy
az alkalmazási terület ennél jóval szélesebb. Például:
képzeljük el, hogy van egy igen fontos monokróm képünk --
pocsék ábrázolással. Alakítsuk át köztes file formájába a
legjobb algoritmus segítségével. Ezután az eredetit akár ki
is dobhatjuk, csak a köztes file-ra lesz szükségünk.
Válasszuk ki a legszebb eljárást a megjelenítési technikák
közül, és rakjuk vissza a képet az eredeti üzemmódba --
csak most már a köztes file-ból dolgozva, és százszor jobb
minôségben. A keletkezett kép alighanem klasszisokkal jobb
lesz, mint az eredeti.
Sorozatunk következô részében a CGA és az EGA megjelenítôk
lehetôségeit firtatjuk majd. A VGA sem marad ki, mivel a
hétköznapi halandó számára egyelôre elérhetetlen XGA után a
második helyet foglalja el a grafikát kedvelôk népszerûségi
listáján. Ez azonban külön fejezetet érdemel.
@KNagy Gergely@N